package com.yycx.module.bus.provider.service.impl;

import com.yycx.common.constants.CommonConstants;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.utils.ApiAssert;
import com.yycx.common.utils.DateUtils;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.module.bus.client.entity.*;
import com.yycx.module.bus.provider.mapper.BusCustomRateMapper;
import com.yycx.module.bus.provider.service.BusCustomRateService;
import com.yycx.module.bus.provider.service.BusDrugsService;
import com.yycx.module.bus.provider.service.BusOrderDetailsService;
import com.yycx.module.system.client.entity.SysFormula;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 购货方税率配置接口实现类
 *
 * @author flyme
 * @date 2020-08-17
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BusCustomRateServiceImpl extends BaseServiceImpl<BusCustomRateMapper, BusCustomRate> implements BusCustomRateService {

    @Autowired
    private BusDrugsService drugsService;

    @Autowired
    private BusOrderDetailsService orderDetailsService;

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, BusCustomRate bcr, EntityMap extra) {
        bcr.setConfigState(CommonConstants.ENABLED);
        Long supplierId = bcr.getSupplierId();
        Long deptId = bcr.getDeptId();
        List<BusSupplierRate> list = new ArrayList<>();
        if (FlymeUtils.isNotEmpty(supplierId)) {
            //市场费率配置-供应商为配置主体
            list = selectBySupplierId(supplierId);
        }
        Long drugsId = bcr.getDrugsId();
        if (FlymeUtils.isNotEmpty(drugsId) && FlymeUtils.isEmpty(deptId)) {
            //市场费率配置-药品为配置主体
            list = selectByDrugsId(drugsId);
        }
        if (FlymeUtils.isNotEmpty(deptId)) {
            BusDrugs drugs = drugsService.getById(drugsId);
            bcr.setSupplierId(drugs.getSupplierId());
            //部门价格配置
            list = selectByDeptId(deptId,drugsId);
            if (FlymeUtils.isNotEmpty(list)) {
                return ResultBody.failed("请不要重复配置");
            }
        }
        if (FlymeUtils.isEmpty(list)) {
            bcr.setEndDate(null);
        }
        extra.put("list", list);
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterAdd(CriteriaSave cs, BusCustomRate busCustomRate, EntityMap extra) {
        List<BusCustomRate> list = extra.get("list");
        if (FlymeUtils.isNotEmpty(list)) {
            BusCustomRate customRate = list.get(0);
            //计算旧配置截至日期
            customRate.setEndDate(DateUtils.plusDateDays(busCustomRate.getBeginDate(), -1));
            //禁用旧配置
            customRate.setConfigState(CommonConstants.DISABLED);
            saveOrUpdate(customRate);
        }
        return super.afterAdd(cs, busCustomRate, extra);
    }


    /**
     * 查询购货方税率全局费率配置
     *
     * @param supplierId
     * @return
     */
    private List<BusSupplierRate> selectBySupplierId(Long supplierId) {
        CriteriaQuery cq = new CriteriaQuery(BusCustomRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.isNull("drugsId");
        cq.orderByDesc("beginDate");
        return list(cq);
    }

    /**
     * 查询部门税率配置
     *
     * @param deptId
     * @return
     */
    private List<BusSupplierRate> selectByDeptId(Long deptId,Long drugsId) {
        CriteriaQuery cq = new CriteriaQuery(BusCustomRate.class);
        cq.eq(true, "deptId", deptId);
        cq.eq(true, "drugsId", drugsId);
        cq.orderByDesc("beginDate");
        return list(cq);
    }

    /**
     * 查询购货方税率某药品费率配置
     *
     * @param drugsId
     * @return
     */
    private List<BusSupplierRate> selectByDrugsId(Long drugsId) {
        CriteriaQuery cq = new CriteriaQuery(BusCustomRate.class);
        cq.eq(true, "drugsId", drugsId);
        cq.isNotNull("supplierId");
        cq.orderByDesc("beginDate");
        return list(cq);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<BusCustomRate> cq, BusCustomRate bcr, EntityMap requestMap) {
        cq.select(BusCustomRate.class, "*");
        cq.eq(BusCustomRate.class, "supplierId");
        cq.eq(BusCustomRate.class, "drugsId");
        cq.addSelect("s_formula.formulaContent s_formulaContent");
        cq.orderByDesc("bcr.beginDate");
        cq.createJoin(SysFormula.class).setJoinAlias("s_formula").setMainField("settleFormulaId");
        return ResultBody.ok();
    }


    @Override
    public BusCustomRate findCustomRate(BusOrderDetails orderDetails, BusOrder busOrder) {

        Long customRateId=orderDetails.getCustomRateId();
        if(FlymeUtils.isNotEmpty(customRateId)){
            return  getById(customRateId);
        }
        //供应商ID
        Long supplierId = orderDetails.getSupplierId();
        ApiAssert.isNotEmpty("供应商supplierId不能为空", supplierId);
        //药品ID
        Long drugsId = orderDetails.getDrugsId();
        //部门ID
        Long deptId = orderDetails.getDeptId();
        //资信方式
        Integer customBondType = busOrder.getCustomBondType();
        ApiAssert.isNotEmpty("资信方式delivery不能为空", customBondType);
        //发货日期
        Date sendDate = busOrder.getSendDate();
        //回款日期
        Date takeDate = busOrder.getTakeDate();
        //查询费率使用的日期
        Date date = sendDate;
        if (customBondType.equals(0)) {
            //全款使用回款日期,资信使用发货日期
            date = takeDate;
        }
        BusCustomRate result = findByAllCondition(supplierId, drugsId, date);
        if (FlymeUtils.isEmpty(result)) {
            result = findWithNullEndDate(supplierId, drugsId, date);
        }
        if (FlymeUtils.isEmpty(result)) {
            result = findBySupplierIdAndAllDate(supplierId, date);
        }
        if (FlymeUtils.isEmpty(result)) {
            result = findBySupplierIdWithNullEndDate(supplierId, date);
        }
        BigDecimal customSettleRate=orderDetails.getCustomSettleRate();
        BigDecimal customSettleGapUpTaxRate=orderDetails.getCustomSettleGapUpTaxRate();
        BigDecimal customTaxRate=orderDetails.getCustomTaxRate();
        if(FlymeUtils.isNotEmpty(result)){
            if(FlymeUtils.isNotEmpty(customSettleRate)){
                result.setCustomSettleRate(customSettleRate);
            }
            if(FlymeUtils.isNotEmpty(customSettleGapUpTaxRate)){
                result.setCustomSettleGapUpTaxRate(customSettleGapUpTaxRate);
            }
            if(FlymeUtils.isNotEmpty(customTaxRate)){
                result.setCustomTaxRate(customTaxRate);
            }
        }else{
            BusOrderDetails  old = orderDetailsService.getById(orderDetails.getOrderDetailsId());
            if(FlymeUtils.isNotEmpty(old)){
                result=new BusCustomRate();
                result.setCustomSettleRate(old.getCustomSettleRate());
                result.setCustomTaxRate(old.getCustomTaxRate());
                result.setCustomSettleGapUpTaxRate(old.getCustomSettleGapUpTaxRate());
            }
        }
        ApiAssert.isNotEmpty("购货方费率未配置", result);
        return result;
    }

    /**
     * 根据日期药品查询配置
     *
     * @param supplierId
     * @param drugsId
     * @param date
     * @return
     */
    private BusCustomRate findByAllCondition(Long supplierId, Long drugsId, Date date) {
        CriteriaQuery cq = new CriteriaQuery(BusCustomRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.eq(true, "drugsId", drugsId);
        cq.le(true, "beginDate", date);
        cq.ge(true, "endDate", date);
        cq.orderByDesc("beginDate");
        cq.last("limit 1");
        return getOne(cq);
    }


    /**
     * 根据日期(无结束日期)和药品查询配置
     *
     * @param supplierId
     * @param drugsId
     * @param date
     * @return
     */
    private BusCustomRate findWithNullEndDate(Long supplierId, Long drugsId, Date date) {
        CriteriaQuery cq = new CriteriaQuery(BusCustomRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.eq(true, "drugsId", drugsId);
        cq.le(true, "beginDate", date);
        cq.last("limit 1");
        cq.orderByDesc("beginDate");
        return getOne(cq);
    }


    /**
     * 根据供应商按开始日期和截至日期查询
     *
     * @param supplierId
     * @param date
     * @return
     */
    private BusCustomRate findBySupplierIdAndAllDate(Long supplierId, Date date) {
        CriteriaQuery cq = new CriteriaQuery(BusCustomRate.class);
        cq.le(true, "beginDate", date);
        cq.ge(true, "endDate", date);
        cq.eq(true, "supplierId", supplierId);
        cq.orderByDesc("beginDate");
        cq.last("limit 1");
        return getOne(cq);
    }

    /**
     * 根据供应商按开始日期查询
     *
     * @param supplierId
     * @param date
     * @return
     */
    private BusCustomRate findBySupplierIdWithNullEndDate(Long supplierId, Date date) {
        CriteriaQuery cq = new CriteriaQuery(BusCustomRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.le(true, "beginDate", date);
        cq.orderByDesc("beginDate");
        cq.last("limit 1");
        return getOne(cq);
    }

    /**
     * 查询部门价格配置
     *
     * @param supplierId
     * @param drugsId
     * @param deptId
     * @return
     */
    @Override
    public BusCustomRate findByDeptId(Long supplierId, Long drugsId, Long deptId) {
        CriteriaQuery cq = new CriteriaQuery(BusCustomRate.class);
        cq.eq(true, "supplierId", supplierId);
        cq.eq(true, "drugsId", drugsId);
        cq.eq(true, "deptId", deptId);
        cq.last("limit 1");
        BusCustomRate busCustomRate = getOne(cq);
        if (FlymeUtils.isEmpty(busCustomRate)) {
            BusDrugs busDrugs = drugsService.getById(drugsId);
            busCustomRate = new BusCustomRate();
            busCustomRate.setSettlePrice(busDrugs.getSettlePrice());
        }else{
            BigDecimal settlePrice=busCustomRate.getSettlePrice();
            if(FlymeUtils.isEmpty(settlePrice)){
                BusDrugs busDrugs = drugsService.getById(drugsId);
                busCustomRate.setSettlePrice(busDrugs.getSettlePrice());
            }
        }
        return busCustomRate;
    }
}
